# ~*~ coding: utf-8 ~*~
import traceback
from flask import current_app
from flask_login import current_user
from flask_socketio import join_room, Namespace
from .models import WSProxy
from ..models import Task
from ...extensions import db


from .deployer import Deployer


class CodesSocketIO(Namespace):
    def __init__(self, namespace=None):
        super(CodesSocketIO, self).__init__(namespace=namespace)
        print('init CodesSocketIO ....')
        self.room, self.task_id, self.project_id = None, None, None

    def on_open(self, message):
        current_app.logger.info(message)
        if 'task_id' in message:
            self.task_id = message['task_id']
            self.room = self.task_id
        if 'project_id' in message:
            self.project_id = message['project_id']
            self.room = self.project_id

        if not current_user.is_authenticated:
            self.emit('close', {'event': 'disconnect', 'data': {}}, room=self.room)

        join_room(room=self.room)
        WSProxy.new_wsproxy(self, self.room)
        self.emit('construct', {'event': 'connect', 'data': {}}, room=self.room)

    def on_deploy(self, message=None):
        current_app.logger.info('start deploy')

        task = db.session.query(Task).get(self.room)
        if not task.is_deploy:
            self.emit('deploy', {'event': 'error', 'data': '该工单已上线成功，不能重复上线！'}, room=self.room)
        else:
            deploy = Deployer(task_id=self.room)
            try:
                deploy.deploy()
                self.emit('deploy', {'event': 'deploy', 'data': '恭喜您，工单上线成功！'}, room=self.room)
            except Exception as e:
                current_app.logger.error(traceback.format_exc())
                self.emit('deploy', {'event': 'error', 'data':  '该工单已上线失败，请联系管理员！'}, room=self.room)

    def on_rollback(self, message=None):
        current_app.logger.info('start rollback')
        deploy = Deployer(task_id=self.room)

        task = db.session.query(Task).get(self.room)
        if not task.is_rollback:
            self.emit('rollback', {'event': 'error', 'data': '该工单已回滚成功，不能重复回滚！'}, room=self.room)
        else:
            try:
                deploy.rollback()
                self.emit('rollback', {'event': 'rollback', 'data': '恭喜您，工单回滚成功！'}, room=self.room)
            except Exception as e:
                current_app.logger.error(traceback.format_exc())
                self.emit('rollback', {'event': 'error', 'data': '该工单已上线失败，请联系管理员！'}, room=self.room)

    def on_branches(self, message=None):
        current_app.logger.info('start branches')
        revision = Deployer(project_id=self.room)
        try:
            branches = revision.list_branch()
            self.emit('branches', {'event': 'branches', 'data': branches}, room=self.room)
        except Exception as e:
            current_app.logger.error(traceback.format_exc())
            self.emit('branches', {'event': 'error', 'data': '获取版本信息失败，请联系管理员！'}, room=self.room)

    def on_tags(self, message=None):
        current_app.logger.info('start tags')
        revision = Deployer(project_id=self.room)
        try:
            tags = revision.list_tag()
            self.emit('tags', {'event': 'tags', 'data': tags}, room=self.room)
        except Exception as e:
            current_app.logger.error(traceback.format_exc())
            self.emit('tags', {'event': 'error', 'data': '获取版本信息失败，请联系管理员'}, room=self.room)

    def on_ping(self, message=None):
        current_app.logger.info('start ping')
        import time
        self.emit(
            'pong',
            {
                'event': 'ping:pong',
                'data': {'time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))}
            },
            room=self.room
        )
